% !Mode:: "TeX:UTF-8"

\chapter{项目设计文档}

\section{系统总体设计}

随着现代化、城市化的发展速度加快，外卖行业的市场规模在不断扩大。为增强企业的竞争力，企划开发一款“饿了么”外卖App，以满足当代人们日渐增长的
便捷饮食需求，并为线下的饮食商家提供线上销售的接口，同时，该App具有满足用户个性化需求、存储历史订单、推荐适宜商家的功能。

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.3\textwidth]{jiegougai}
  \caption{设计结构概述}\label{fig:jiegougai}
  \vspace{\baselineskip}
  \end{figure}
  
结合现有的系统代码结构和情况，考虑使用Springboot + Vue3的方案来设计该“饿了么”外卖平台App，采用前后端分离的策略，从而方便
前后端的代码实现和前后端接口的设计。

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.5\textwidth]{jiagou}
  \caption{整体技术架构}\label{fig:jiagou}
  \vspace{\baselineskip}
  \end{figure}

\section{数据库设计说明}

\subsection{用户端数据库设计}
用户相关数据表如下。

用户信息表（user）
\begin{table}[htbp]
  \caption{用户信息表}\label{tab:user}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & userId & varchar&用户编号\\
    2 & password &varchar&密码 \\
    3 & usesName &varchar&用户名称\\
    4 & usesSex &int&用户性别\\
    5 & useImg &mediumtext&用户头像\\
    6 & delTag &int&删除标记\\
    7 & userType &varchar&用户类型\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}

用户购物车表（cart）
\begin{table}[htbp]
  \caption{用户购物车表}\label{tab:cart}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & cartId & int&编号\\
    2 & foodId &int&食品编号 \\
    3 & businessId &int&所属商家编号\\
    4 & userId &varchar&所属用户编号\\
    5 & quantity &int&购买数量\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}

订单明细表（orderdetials）
\begin{table}[htbp]
  \caption{用户订单表}\label{tab:orderdetials}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & odId & int&订单明细编号\\
    2 & orderId &int&所属订单编号 \\
    3 & foodId &int&所属食品编号\\
    4 & quantity &int&数量\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
    

用户订单表（orders）

\begin{table}[H]
  \caption{用户订单表}\label{tab:orders}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & orderId & int&订单编号\\
    2 & userId &varchar&所属用户编号 \\
    3 & businessId &int&所属商家编号\\
    4 & orderDate &varchar&订单日期\\
    5 & orderTotal &decimal&订单总价\\
    6 & daId &int&送货地址编号\\
    7 & orderState&int&订单状态\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
  

头像表（images）

\begin{table}[H]
  \caption{头像表}\label{tab:img}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & imgId & int&头像编号\\
    2 & imgData &mediumtext&头像Base64编码 \\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
    

用户地址表（deliveryaddress）

\begin{table}[H]
  \caption{用户订单表}\label{tab:deliveryaddress}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & daId & int&送货地址编号\\
    2 & contactName &varchar&联系人姓名 \\
    3 & contactSex &int&联系人性别\\
    4 & contactTel &varchar&联系人电话\\
    5 & address &decimal&送货地址\\
    6 & userId &int&所属用户编号\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
  

\subsection{商家端数据库设计}
商家相关数据表如下。

商家信息表（business）

\begin{table}[H]
  \caption{商家信息表}\label{tab:business}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & businessId & int&商家编号\\
    2 & businessName &varchar&商家名称 \\
    3 & businessAddress &varchar&商家地址\\
    4 & businessExplain &varchar&商家介绍\\
    5 & businessImg &mediumtext&商家图片\\
    6 & orderTypeId &int&点餐分类\\
    7 & starPrice&decimal&起送费\\
    8 & deviveryPrice &decimal&配送费\\
    9 & remarks&varchar&备注\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
  
食品表（food）

\begin{table}[H]
  \caption{食品表}\label{tab:food}
  \vspace{0.5em}\wuhao
  \begin{tabularx}{\textwidth}{XXXX}
  \toprule[1.5pt]
    No & 字段名 & 数据类型 &说明\\\midrule[1pt]
    1 & foodId & int&食品编号\\
    2 & foodName &varchar&食品名称 \\
    3 & foodExplain &varchar&食品介绍\\
    4 & foodImg &mediumtext&食品图片\\
    5 & foodPrice &decimal&食品价格\\
    6 & businessId &int&所属商家编号\\
    7 & remarks&varchar&备注\\
    \bottomrule[1.5pt]
    \end{tabularx}
    \vspace{\baselineskip}
    \end{table}
  


\section{接口设计说明}

\subsection{前后端大接口}

\subsubsection{用户信息管理}
\begin{itemize}
  \item  \textbf{注册}
  
UserController/saveUser

参数：User user

返回值：response,success为注册成功，error为注册失败

功能：向数据表user中加入新的一列，表示增加一个新用户

  \item \textbf{登录}
  
  UserController/getUserByIdByPass
  
  参数：User user
  
  返回值：response,success为注册成功，error为注册失败
  
  功能：验证用户输入的账号密码是否有与数据库中存储得一致，返回信息
  
  \item \textbf{修改个人信息}
  
  UserController/updateUserById
  
  参数：User user
  
  返回值：int（0、1）1成功、0失败
  
  功能：修改数据库中相应信息，将前端输入的信息传入数据库
  
  \item \textbf{注销账户}
  
  UserController/removeUser
  
  参数：User user
  
  返回值：int（0、1）1成功、0失败
  
  功能：删除数据库中相应信息
\end{itemize}



\subsubsection{用户订单管理}
\begin{itemize}
  \item  \textbf{创建订单}
  
  OrdersController/createOrders

参数：Orders orders

返回值：int（0、1）1成功、0失败

功能：向数据表orders中加入新的一列，表示增加一个新的订单

  \item \textbf{列举订单}
  
  OrdersController/listOrdersByUserId
  
  参数：Orders orders
  
  返回值：订单表数组
  
  功能：将所属用户存储在order中的订单信息存储在数组中返回
  
  \item \textbf{支付订单}
  
  OrdersController/turnOrderState
  
  参数：Orders orders
  
  返回值：int（0、1）1成功、0失败
  
  功能：将对应订单的支付状态从1改为0
  
  \item \textbf{查询订单明细}
  
  OrderDetailetController/listOrderDetailetByOrderId
  
  参数：Orders orders
  
  返回值：订单明细表数组
  
  功能：根据订单ID获取订单明细

\end{itemize}

\subsubsection{用户地址管理}
\begin{itemize}
  \item  \textbf{列举地址}
  
  DeliveryAddressController/listDeliveryAddressByUserId

参数：DeliveryAddress deliveryAddress

返回值：地址表数组

功能：根据用户ID列举地址表数组

  \item \textbf{新增地址}
  
  DeliveryAddressController/saveDeliveryAddress
  
  参数：DeliveryAddress deliveryAddress
  
  返回值：int（0、1）1成功、0失败
  
  功能：向Address表中插入新的列，表示增加一个新的地址
  
  \item \textbf{修改地址}
  
  DeliveryAddressController/updateDeliveryAddress
  
  参数：DeliveryAddress deliveryAddress
  
  返回值：int（0、1）1成功、0失败
  
  功能：修改数据表中相应地址的相应信息
  
  \item \textbf{删除地址}
  
  DeliveryAddressController/removeDeliveryAddress
  
  参数：DeliveryAddress deliveryAddress

  返回值：int（0、1）1成功、0失败
  
  功能：删除数据库中相应地址信息

\end{itemize}

\subsubsection{用户购物车管理}
\begin{itemize}
  \item  \textbf{列举购物车}
  
  CartController/listCart

参数：Cart cart

返回值：response信息

功能：根据用户ID列举Cart数组

  \item \textbf{新增购物车}
  
  CartController/saveCart
  
  参数：Cart cart
  
  返回值：response信息
  
  功能：向Cart表中插入新的列，表示增加一个新的地址
  
  \item \textbf{修改购物车}
  
  CartController/updateCart
  
  参数：Cart cart
  
  返回值：response信息
  
  功能：修改数据表中相应购物车的相应信息
  
  \item \textbf{删除购物车}
  
  CartController/removeCart
  
  参数：Cart cart

  返回值：response信息
  
  功能：删除数据库中相应购物车信息

\end{itemize}


\subsubsection{商家信息管理}
\begin{itemize}
  \item  \textbf{列举商家}
  
  BusinessController//listBusinessByOrderTypeId/{orderTypeId}

参数：Integer orderTypeId

返回值：response信息

功能：根据商家的分类ID列举商家数组

  \item \textbf{查找商家}
  
  BusinessController/getBusinessById/{businessId}
  
  参数：Integer businessId
  
  返回值：response信息
  
  功能：根据商家的ID列举商家信息
  
  \item \textbf{新增商家}
  
  BusinessController/saveBusiness
  
  参数：Business business
  
  返回值：response信息
  
  功能：向Business表中插入新的列，表示增加一个新的商家
  
  \item \textbf{列举商品}
  
  FoodController/listFoodByBusinessId
  
  参数：Food food

  返回值：food数据表数组
  
  功能：根据商家的ID列举商家的商品数组

  \item \textbf{修改商品信息}
  
  FoodController/updateFood
  
  参数：Food food

  返回值：response信息
  
  功能：修改数据表中相应商品的相应信息
\end{itemize}


\subsection{后端内部接口}

\begin{itemize}
  \item  \textbf{用户操作部分}
  
  service层提供给controller的接口

  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{userSer}
    \caption{用户信息接口}\label{fig:userSer}
    \vspace{\baselineskip}
    \end{figure}
  
  getUserByIdByPass：确认用户输入的账号密码是否正确

  getUserById：查询用户

  saveUser：注册用户

  updateUserById：修改用户信息

  removeUser：注销用户

  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{cartSer}
    \caption{用户购物车接口}\label{fig:cartSer}
    \vspace{\baselineskip}
    \end{figure}
  
  listCart：列举购物车信息

  saveCart：将商品加入购物车

  updateCart：更新购物车

  removeCart：删除数据库中相应购物车信息
  
  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{odSer}
    \caption{用户订单接口}\label{fig:odSer}
    \vspace{\baselineskip}
    \end{figure}

  createOrders：创建订单

  getOrdersById：查询订单

  listOrdersByUserId：列举用户订单

  turnOrderState：转换用户订单状态，支付订单

  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{odeSer}
    \caption{用户订单明细接口}\label{fig:odeSer}
    \vspace{\baselineskip}
    \end{figure}

  saveOrderDetailetBench：批量保存订单明细

  listOrderDetailetByOrderId：根据订单ID获取订单明细

    \begin{figure}[H]
      \centering
      \includegraphics[width=0.7\textwidth]{addSer}
      \caption{用户地址接口}\label{fig:addSer}
      \vspace{\baselineskip}
      \end{figure}

  listDeliveryAddressByUserId：列举用户地址

  getBusinessById：获取用户地址

  saveDeliveryAddress：新增用户地址

  updateDeliveryAddress：修改用户地址

  removeDeliveryAddress：删除用户地址

  \hspace*{\fill}

  \item  \textbf{商家操作部分}
  
  service层提供给controller的接口
  
  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{businessSer}
    \caption{商家信息接口}\label{fig:businessSer}
    \vspace{\baselineskip}
    \end{figure}

  listBusinessByOrderTypeId：根据商家的分类ID列举商家数组

  getBusinessById：根据商家的ID列举商家信息

  saveBusiness：新增新的商家
  
 \begin{figure}[H]
      \centering
      \includegraphics[width=0.7\textwidth]{foodSer}
      \caption{商家商品接口}\label{fig:foodSer}
      \vspace{\baselineskip}
      \end{figure}

  listFoodByBusinessId：根据商家的ID列举商家的商品数组

  updateFood：修改数据表中相应商品的相应信息

\end{itemize}

\section{业务对象设计说明}

该部分从横向和纵向两个角度分析项目的业务对象设计，主要描述项目的
代码架构和功能模块。

\begin{itemize}
  \item  \textbf{横向分析-代码架构}
  
  后端代码基于SPringBoot框架，主要分为三层架构，分别为Service层、Mapper层和Controller层，
  结构如下图所示。
  
  \begin{figure}[H]
    \centering
    \includegraphics[width=0.7\textwidth]{sanceng}
    \caption{SpringBoot三层架构}\label{fig:sanceng}
    \vspace{\baselineskip}
    \end{figure}

    controller层向上层即前端提供接口，使得前端可以调用后端接口，起到了连接前后端的作用，在该项目中controller层单独存储在controller文件夹中。
    需要说明的是，在该层的设计中，选择了多种方式使代码结构更完善，如引入DTO类，以保证只从后端传送必要的信息到前端，而不暴露用户的隐私信息；
    以及修改前后端接口形式，使其更加满足RESTful风格。


    service层实现具体业务代码，向下调用Mapper层的函数以向数据库获取数据，向上实现Controller层提供
    给前端的接口的具体逻辑。该外卖App中的service层提供给controller层的接口集合放在Service文件夹中(如上文所展示的一样)，
    具体的实现放在ServiceImpl类中(如下图~\ref{fig:impl}~所示)，这体现了面向接口而非实现编程的设计原则。

    \begin{figure}[H]
      \centering
      \includegraphics[width=0.7\textwidth]{impl}
      \caption{ServiceImpl类实现示例}\label{fig:impl}
      \vspace{\baselineskip}
      \end{figure}

    Mapper层分为主要分为两个部分，分别为负责用户信息查询删改的userMapper、ordersMapper、orderdetialetMapper、cartMapper等，以及负责商家信息查询删改的
    BusinessMapper、foodMapper等。这些都体现了SRP 单一职责设计原则，部分实现如下~\ref{fig:impl}~所示。

    \begin{figure}[H]
      \centering
      \includegraphics[width=0.8\textwidth]{controller}
      \caption{Mapper层实现示例}\label{fig:controller}
      \vspace{\baselineskip}
      \end{figure}

   \item  \textbf{纵向分析-功能模块}
   
   该项目的功能模块主要分为两类，分别为用户功能模块和商家功能模块，两个模块内部本身涉及的业务逻辑比较简单，即增加、删除、修改、查询等；值得一提的是该项目在用户
   注册时即将用户分为客户和商家两类，注册成功后后续登陆时也会分别对应不同身份，具有不同功能。下面进行具体解释。
   \begin{enumerate}
    \item{用户区分模块：}
    在数据库表user中设置usertype属性，来区分用户是商家或是客户。在注册页面，前端设置选项按钮，来决定用户身份；后端接收到前端的选项数据后，
    填入usertype属性，并与之对应地增加商家表或用户表。
    \item{用户功能模块：}
    不同的用户身份具有不同的用户功能。例如，商家模块中，商家可以修改商品名称、价格、简介等，可以增加商品、删除商品；
    客户模块中，客户可以点餐加入购物车、形成订单、支付订单、取消订单等。由于前文均有详细说明，在此处不一一赘述。
  \end{enumerate}
  \end{itemize}
